//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <_critsec.h>
#include <interlocked.h>
#include <assert.h>
#include <elacfg.h>
#include <csdetect.h>
#include <pseudo.h>
#include <aura.h>

ECode _CCriticalSection::Initialize()
{
//    cLock = 0;
    cNested = 0;
    nOwnerId = 0;
    event = NULL;

#ifndef _RELEASE
    reserved = this;
#endif

    //return CPseudoKernel::SystemEvent_Create(&event);
    return (ECode)AuraCriticalSection_Create(&event);

}

void _CCriticalSection::Terminate()
{
    //assert(this == reserved);

    if (NULL != event) {
        //CPseudoKernel::SystemEvent_Destroy(event);
        AuraCriticalSection_Destroy(event);
        event = NULL;
    }

#ifndef _RELEASE
    reserved = NULL;
#endif
    return ;
}

void _CCriticalSection::Enter()
{
//    ThreadId id ;
//
//    assert(this == reserved);
//    CPseudoKernel::Thread_GetCurrentId(&id);
//    CSDETECT_DEADLOCK_DETECTION
//
//    if (InterlockedCompareExchange((Int32 *)&nOwnerId, id, 0) != 0) {
//        if (nOwnerId != id) {
//            InterlockedIncrement(&cLock);
//            while (InterlockedCompareExchange(
//                    (Int32 *)&nOwnerId, id, 0) != 0) {
//                CSDETECT_INSERT_INTO_CSWAITLIST
//
//                CPseudoKernel::SystemEvent_Wait(event);
//                CSDETECT_DETACH_FROM_CSWAITLIST
//
//                CSDETECT_DEADLOCK_DETECTION
//            }
//
//            InterlockedDecrement(&cLock);
//        }
//    }
//    cNested++;
    AuraCriticalSection_Enter(event);

    return ;
}

ECode _CCriticalSection::TryEnter(Boolean *pEntered)
{
//    ThreadId id;
//    assert(this == reserved);
    if (NULL == pEntered) {
        return E_INVALID_ARGUMENT;
    }
//    CPseudoKernel::Thread_GetCurrentId(&id);
//    if (InterlockedCompareExchange((Int32 *)&nOwnerId, id, 0) != 0) {
//        if (nOwnerId != id) {
//            *pEntered = FALSE;
//            return NOERROR;
//        }
//    }
//    cNested++;
//    *pEntered = TRUE;
    AuraCriticalSection_TryEnter(event, pEntered);
    return NOERROR;
}

void _CCriticalSection::Leave()
{
//    assert(this == reserved);
//    assert(0 < cNested);
//
//    cNested--;
//    if (0 == cNested) {
//        nOwnerId = 0;
//    }
//    CPseudoKernel::SystemEvent_Notify(event);
    AuraCriticalSection_Leave(event);

    return ;
}

